import cgi
import datetime
import urllib
import wsgiref.handlers
import os
import random
import math

from google.appengine.ext.webapp import template
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.api import users
from google.appengine.ext.webapp.util import run_wsgi_app

class User(db.Model):
	usi = db.StringProperty()
	firstname = db.StringProperty()
	lastname = db.StringProperty()
	spouseusi = db.StringProperty()
	dob = db.DateProperty()
	x = db.IntegerProperty()
	y = db.IntegerProperty()
	sex = db.StringProperty()
	fatherusi = db.StringProperty()
	motherusi = db.StringProperty()
	createddate = db.DateProperty(auto_now_add=True)
	imageurl = db.StringProperty()

class UserDisplay:
	def __init__(self, user):
		self.usi = user.usi
		self.name = "%s %s" % (user.firstname, user.lastname)
		self.spouseusi = user.spouseusi
		self.childrenArray = get_childrenArray(user)
		self.fatherusi = user.fatherusi
		self.motherusi = user.motherusi
		self.x = user.x
		self.y = user.y
		self.sex = user.sex
		self.imageurl = user.imageurl

def get_all_users():
	"""Returns all the users available in the datastore"""
	users = db.GqlQuery("SELECT * "
						"FROM User "
						"ORDER BY dob DESC LIMIT 100")

	return users

def get_user_by_usi(usi):
	"""returns the user by the parameter usi"""
	users = get_all_users()

	for user in users:
		if user.usi == usi:
			return user

def getUsi():
	"""Returns a Random Usi"""
	alpha = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

	for a in alpha:
		for b in alpha:
			usi = "%s%s" % (a, b)
			query = db.GqlQuery("SELECT * "
								"FROM User "
								"WHERE usi = :1", usi)

			q = query.fetch(101)

			if len(q) == 0:
				return usi

def get_childrenArray(user):
	"""returns the array of children for a specific user through the parameter user"""
	if user.sex == 'Male':
		return db.GqlQuery("SELECT * FROM User WHERE fatherusi = :1 ORDER BY dob DESC LIMIT 101", user.usi)
	elif user.sex == 'Female':
		return db.GqlQuery("SELECT * FROM User WHERE motherusi = :1 ORDER BY dob DESC LIMIT 101", user.usi)

class MainPage(webapp.RequestHandler):
	def get(self):
		type = self.request.get('type')
		users = get_all_users()

		userDisplay = []

		i = 0
		for user in users:
			userDisplay.append(UserDisplay(user))
			i = i + 1

		if type == "raw":
			template_values = {
				'users': users
			}
			path = os.path.join(os.path.dirname(__file__), 'index2.html')
		elif type == "assign":
			template_values = {
				'users': userDisplay
			}
			path = os.path.join(os.path.dirname(__file__), 'index3.html')
		else:
			template_values = {
				'users': userDisplay,
				'len': len(userDisplay)
			}
			path = os.path.join(os.path.dirname(__file__), 'index.html')
		
		self.response.out.write(template.render(path, template_values))

class Register(webapp.RequestHandler):
	def get(self):
		type = self.request.get('type')
		if type == 'edit':
			usi = self.request.get('usi')

			q = get_user_by_usi(usi)

			dobdate = q.dob.day
			dobyear = q.dob.year
			dobmonth = q.dob.month

		datearray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
		montharray = [{'i': 1, 'm': 'Jan'}, {'i': 2, 'm': 'Feb'}, {'i': 3, 'm': 'Mar'}, {'i': 4, 'm': 'Apr'}, {'i': 5, 'm': 'May'}, {'i': 6, 'm': 'Jun'}, {'i': 7, 'm': 'Jul'}, {'i': 8, 'm': 'Aug'}, {'i': 9, 'm': 'Sep'}, {'i': 10, 'm': 'Oct'}, {'i': 11, 'm': 'Nov'}, {'i': 12, 'm': 'Dec'}]

		now = datetime.datetime.now()

		males = db.GqlQuery("SELECT * "
							"FROM User "
							"WHERE sex = 'Male' "
							"AND dob < :1 "
							"ORDER BY dob DESC LIMIT 100", str(now.year - 18) + "-" + str(now.month) + "-" + str(now.day))

		females = db.GqlQuery("SELECT * "
							"FROM User "
							"WHERE sex = 'Female' "
							"AND dob < :1 "
							"ORDER BY dob DESC LIMIT 100", str(now.year - 18) + "-" + str(now.month) + "-" + str(now.day))

		spouses = db.GqlQuery("SELECT * "
							"FROM User "
							"WHERE dob < :1 "
							"ORDER BY dob DESC LIMIT 100", str(now.year - 18) + "-" + str(now.month) + "-" + str(now.day))


		if type == 'edit':
			template_values = {
				'dates': datearray,
				'months': montharray,
				'dobdate': dobdate,
				'dobyear': dobyear,
				'dobmonth': dobmonth,
				'user': q,
				'type': type,
				'males': males,
				'females': females,
				'spouses': spouses
			}
		else:
			template_values = {
				'dates': datearray,
				'months': montharray,
				'type': type,
				'males': males,
				'females': females,
				'spouses': spouses
			}

		path = os.path.join(os.path.dirname(__file__), 'register.html')
		self.response.out.write(template.render(path, template_values))

class ChooseLock(webapp.RequestHandler):
	def post(self):
		spouseusi = self.request.get('spouseusi')
		firstname = self.request.get('firstname')
		lastname = self.request.get('lastname')
		fatherusi = self.request.get('fatherusi')
		motherusi = self.request.get('motherusi')
		sex = self.request.get('sex')
		d = int(self.request.get('date'))
		m = int(self.request.get('month'))
		y = int(self.request.get('year'))
		
		template_values = {
			'spouseusi': spouseusi,
			'firstname': firstname,
			'lastname': lastname,
			'fatherusi': fatherusi,
			'motherusi': motherusi,
			'sex': sex,
			'd': d,
			'm': m,
			'y': y
		}

		path = os.path.join(os.path.dirname(__file__), 'chooseplacement.html')
		self.response.out.write(template.render(path, template_values))
		

class UploadToDataStore(webapp.RequestHandler):
	def post(self):
		firstname = self.request.get('firstname')
		lastname = self.request.get('lastname')
		sex = self.request.get('sex')
		d = int(self.request.get('date'))
		m = int(self.request.get('month'))
		y = int(self.request.get('year'))
		date = datetime.date(y, m, d)
		x = int(self.request.get('x'))
		fatherusi = self.request.get('fatherusi')
		motherusi = self.request.get('motherusi')
		y = int(self.request.get('y'))

		usi = getUsi()

		spouseusi = self.request.get('spouseusi')
		spouse = get_user_by_usi(spouseusi)
		if spouse:
			spouse.spouseusi = usi
			spouse.put()

		user = User()
		user.dob = date
		user.usi = usi
		user.firstname = firstname
		user.lastname = lastname
		user.fatherusi = fatherusi
		user.motherusi = motherusi
		user.x = x
		user.y = y
		user.spouseusi = spouseusi
		user.sex = sex
		user.imageurl = 'pics/%s-avatar.png' % sex
		user.put()

		self.redirect('/')

class UploadEditedModel(webapp.RequestHandler):
	def post(self):
		usi = self.request.get('usi')

		q = get_user_by_usi(usi)

		firstname = self.request.get('firstname')
		lastname = self.request.get('lastname')
		sex = self.request.get('sex')
		d = int(self.request.get('date'))
		m = int(self.request.get('month'))
		y = int(self.request.get('year'))
		date = datetime.date(y, m, d)

		if self.request.get('spouseusi') == '':
			spouseusi = ''
		else:
			spouseusi = self.request.get('spouseusi')

		if self.request.get('fatherusi') == '':
			fatherusi = ''
		else:
			fatherusi = self.request.get('fatherusi')

		if self.request.get('motherusi') == '':
			motherusi = ''
		else:
			motherusi = self.request.get('motherusi')


		q.dob = date
		q.firstname = firstname
		q.lastname = lastname
		q.fatherusi = fatherusi
		q.motherusi = motherusi
		q.spouseusi = spouseusi
		q.sex = sex
		q.put()

		self.redirect('/')


class Detail(webapp.RequestHandler):
	def get(self):

		usi = self.request.get('usi')

		q = get_user_by_usi(usi)

		hasspouse = True
		hasfather = True
		hasmother = True

		spouseusi = q.spouseusi
		if spouseusi == '':
			hasspouse = False

		fatherusi = q.fatherusi
		if fatherusi == '':
			hasfather = False

		motherusi = q.motherusi
		if motherusi == '':
			hasmother = False

		spo = q
		fat = q
		mom = q

		if hasspouse:
			spo = get_user_by_usi(q.spouseusi)

		if hasfather:
			fat = get_user_by_usi(q.fatherusi)

		if hasmother:
			mom = get_user_by_usi(q.motherusi)

		template_values = {
			'users': q,
			'spouse': spo,
			'father': fat,
			'mother': mom,
			'hasmother': hasmother,
			'hasfather': hasfather,
			'hasspouse': hasspouse
		}

		path = os.path.join(os.path.dirname(__file__), 'detail.html')
		self.response.out.write(template.render(path, template_values))

class EditPosition(webapp.RequestHandler):
	def post(self):
		users = get_all_users()
		
		for user in users:
			user.x = int(self.request.get(user.usi + 'x'))
			user.y = int(self.request.get(user.usi + 'y'))
			user.put()
	
		self.redirect('/')

class Delete(webapp.RequestHandler):
	def get(self):
		usi = self.request.get('usi')

		q = get_user_by_usi(usi)

		if q.spouseusi:
			spouse = get_user_by_usi(q.spouseusi)
			spouse.spouseusi = ''
			spouse.put()

		children = get_childrenArray(q)
		for child in children:
			if q.sex == 'Male':
				child.fatherusi = ''
				child.put()
			elif q.sex == 'Female':
				child.motherusi = ''
				child.put()

		q.delete()

		self.redirect('/')

application = webapp.WSGIApplication(
									[('/', MainPage),
									('/sign', Register),
									('/doit', UploadToDataStore),
									('/edit', UploadEditedModel),
									('/delete', Delete),
									('/poedit', EditPosition),
									('/ChoosePlacement', ChooseLock),
									('/detail', Detail)],
									debug = True)

def main():
	run_wsgi_app(application)

if __name__ == "__main__":
	main()